package gew.servlets;

import gew.beans.DataFacade2;
import gew.html.HtmlTemplates;
import gew.metadata.CustomSql;
import gew.metadata.Queries;
import gew.services.DimensionValueService;
import gew.services.QueryService;
import gew.system.Labels;
import gew.system.RequestParameter;
import gew.utils.SqlUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "tradeSunburstDataServlet", urlPatterns = {"/tradeSunburstDataServlet"})
public class TradeSunburstDataServlet extends HttpServlet {
    
    @EJB
    private DimensionValueService dvs;

    private static final Long LONG_ZERO = new Long(0);
    private static final String CHILDREN = "children";
    private static final int FIELD_INDEX_LEVEL = 0;
    private static final int FIELD_INDEX_ID = 1;
    private static final int FIELD_INDEX_NAME = 2;
    private static final int FIELD_INDEX_VALUE = 3;
    private static final int FIELD_INDEX_SELECTED = 4;
    private static final int FIELD_INDEX_CODE = 5;
    private static final int FIELD_INDEX_URL_CODE = 6;
    private static final int FIELD_INDEX_COLOR = 7;
    private static final String FIELD_ID = "id";
    private static final String FIELD_NAME = "name";
    private static final String FIELD_VALUE = "value";
    private static final String FIELD_SELECTED = "selected";
    private static final String FIELD_CODE = "code";
    private static final String FIELD_URL_CODE = "url_code";
    private static final String FIELD_COLOR = "color";
    private static final String TITLE = "title";
    private static final String DATA = "data";
    private static final String BALLOON_TEMPLATE_TITLE = "balloonTemplate";

    @EJB
    private DataFacade2 dataFacade2;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setHeader("Cache-Control", "no-cache");
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        RequestParameter requestParameter = new RequestParameter(request, dvs);
        
        String result = SqlUtils.BRACKET_FIGURE_LEFT;
        result = result
                .concat(SqlUtils.QUOTE_DBL)
                .concat(DATA)
                .concat(SqlUtils.QUOTE_DBL)
                .concat(SqlUtils.COLON)
                .concat(getTradeSunburstData(requestParameter));
        result = result
                .concat(SqlUtils.COMMA)
                .concat(SqlUtils.QUOTE_DBL)
                .concat(TITLE)
                .concat(SqlUtils.QUOTE_DBL)
                .concat(SqlUtils.COLON)
                .concat(SqlUtils.QUOTE_DBL)
                .concat(getTradeSunburstTitle(requestParameter))
                .concat(SqlUtils.QUOTE_DBL)                
                ;
        
        result = result
                .concat(SqlUtils.COMMA)
                .concat(SqlUtils.QUOTE_DBL)
                .concat(BALLOON_TEMPLATE_TITLE)
                .concat(SqlUtils.QUOTE_DBL)
                .concat(SqlUtils.COLON)
                .concat(SqlUtils.QUOTE_DBL)
                .concat(getBalloonTemplate(requestParameter))
                .concat(SqlUtils.QUOTE_DBL)                
                ;
        result = result.concat(SqlUtils.BRACKET_FIGURE_RIGHT);
        
        response.getWriter().write(result);
    }
    
    private String getBalloonTemplate(RequestParameter rp) {        
        Integer reporterId = rp.getReporterIds().size() > 0 ? rp.getReporterIds().get(0) : 0;
        Integer tradeFlowId = rp.getTradeFlowIds().size() > 0 ? rp.getTradeFlowIds().get(0) : 0;
        Integer partnerId = rp.getPartnerIds().size() > 0 ? rp.getPartnerIds().get(0) : 0;
        Integer periodId = rp.getPeriodIds().size() > 0 ? rp.getPeriodIds().get(0) : 0;
        
        return HtmlTemplates.getTemplate(HtmlTemplates.TRADE_GRAPH_BALLOON_TEMPLATE)
                .replace("@reporterTitle", Labels.get_UI_TITLE_REPORTER(rp.getLocale()))
                .replace("@tradeFlowTitle", Labels.get_UI_TITLE_TRADE_FLOW(rp.getLocale()))
                .replace("@partnerTitle", Labels.get_UI_TITLE_PARTNER(rp.getLocale()))
                .replace("@periodTitle", Labels.get_UI_TITLE_PERIOD(rp.getLocale()))
                .replace("@tradeValueTitle", Labels.get_UI_TITLE_TRADE_VALUE(rp.getLocale()))
                .replace("@shareOfTitle", Labels.get_UI_TITLE_SHARE_OF(rp.getLocale()))
                .replace("@commodityTitle", Labels.get_UI_TITLE_COMMODITY(rp.getLocale()))
                .replace("@reporter", dvs.getNameById(Queries.CountryDimensionValue, reporterId, rp.getLocale()))
                .replace("@tradeFlow", dvs.getNameById(Queries.TradeFlowDimensionValue, tradeFlowId , rp.getLocale()))
                .replace("@partner", dvs.getNameById(Queries.CountryDimensionValue, partnerId, rp.getLocale()))
                .replace("@period", dvs.getNameById(Queries.PeriodDimensionValue, periodId, rp.getLocale()))                
                ;
    }
    
    private String getTradeSunburstTitle(RequestParameter rp){
        Integer tradeFlowId = rp.getTradeFlowIds().size() > 0 ? rp.getTradeFlowIds().get(0) : 0;
        Integer reporterId = rp.getReporterIds().size() > 0 ? rp.getReporterIds().get(0) : 0;
        Integer partnerId = rp.getPartnerIds().size() > 0 ? rp.getPartnerIds().get(0) : 0;
        Integer periodId = rp.getPeriodIds().size() > 0 ? rp.getPeriodIds().get(0) : 0;
        String tradeFlowGenetivus = dvs.getNameGenById(Queries.TradeFlowDimensionValue, tradeFlowId, rp.getLocale());
        String tradeFlowFontAwesome = dvs.getFontAwesomeById(Queries.TradeFlowDimensionValue, tradeFlowId, rp.getLocale());;
        
        return Labels.get_UI_STRUCTURE_OF(rp.getLocale())
                .concat(tradeFlowGenetivus)                
                .concat(SqlUtils.COLON).concat(SqlUtils.HTML_BR)
                .concat(dvs.getNameById(Queries.CountryDimensionValue, reporterId, rp.getLocale()))
                .concat(SqlUtils.SPACE).concat("<i class='").concat(tradeFlowFontAwesome).concat("'></i>").concat(SqlUtils.SPACE)
                .concat(dvs.getNameById(Queries.CountryDimensionValue, partnerId, rp.getLocale()))
                .concat(SqlUtils.COMMA).concat(SqlUtils.SPACE)
                .concat(periodId.toString())
                ;
    }

    private String getTradeSunburstData(RequestParameter rp) {
        StringBuilder buf = new StringBuilder();

        String q1 = CustomSql.getTradeSunburstData(rp.getReporterIdsCS(), rp.getTradeFlowIdsCS(), rp.getPartnerIdsCS(), rp.getPeriodIdsCS(), rp.getCommodityGroupTypeIdsCS(), rp.getCommodityIdsCS(), rp.getLocaleUrlCode());

        List<Object[]> results = dataFacade2.getSqlQueryResults(q1);

        buf.append(SqlUtils.BRACKET_SQUARE_LEFT);

        if (results.size() > 0) {
            Integer prevLevel = QueryService.getCellValue(results.get(0), FIELD_INDEX_LEVEL, 0);
            ArrayList<Integer> levels = new ArrayList<>();
            levels.add(prevLevel);

            for (Integer i = 0; i < results.size(); i++) {

                Integer currLevel = QueryService.getCellValue(results.get(i), FIELD_INDEX_LEVEL, 0);

                // <editor-fold defaultstate="collapsed" desc="OPEN">
                // Новый элемент - первый
                if (currLevel.equals(prevLevel) && i == 0) {
                    buf.append(SqlUtils.BRACKET_FIGURE_LEFT);
                } // Новый элемент на том же уровне
                else if (currLevel.equals(prevLevel)) {
                    buf
                            .append(SqlUtils.BRACKET_FIGURE_RIGHT)
                            .append(SqlUtils.COMMA)
                            .append(SqlUtils.BRACKET_FIGURE_LEFT);
                } // Новый элемент - дочерний для предыдущего
                else if (currLevel > prevLevel) {
                    buf
                            .append(SqlUtils.COMMA)
                            .append(SqlUtils.QUOTE_DBL).append(CHILDREN).append(SqlUtils.QUOTE_DBL)
                            .append(SqlUtils.COLON)
                            .append(SqlUtils.BRACKET_SQUARE_LEFT)
                            .append(SqlUtils.BRACKET_FIGURE_LEFT);
                    prevLevel = currLevel;
                    levels.add(currLevel);
                } // Новый элемент - выше по уровню
                else if (currLevel < prevLevel) {

                    while (levels.size() > 0 && currLevel < levels.get(levels.size() - 1)) {
                        levels.remove(levels.size() - 1);
                        buf
                                .append(SqlUtils.BRACKET_FIGURE_RIGHT)
                                .append(SqlUtils.BRACKET_SQUARE_RIGHT);
                    }

                    prevLevel = currLevel;

                    buf
                            .append(SqlUtils.BRACKET_FIGURE_RIGHT)
                            .append(SqlUtils.COMMA)
                            .append(SqlUtils.BRACKET_FIGURE_LEFT);
                }

                // </editor-fold>
                
                Integer vId = QueryService.getCellValue(results.get(i), FIELD_INDEX_ID, 0);
                String vName = QueryService.getCellValue(results.get(i), FIELD_INDEX_NAME, "NO NAME");
                Long vTradeValue = QueryService.getCellValue(results.get(i), FIELD_INDEX_VALUE, LONG_ZERO);
                Integer vSelected = QueryService.getCellValue(results.get(i), FIELD_INDEX_SELECTED, 0);
                String vCode = QueryService.getCellValue(results.get(i), FIELD_INDEX_CODE, "0");
                String vUrlCode = QueryService.getCellValue(results.get(i), FIELD_INDEX_URL_CODE, "NA");
                String vColor = QueryService.getCellValue(results.get(i), FIELD_INDEX_COLOR, "NA");

                buf
                        .append(SqlUtils.QUOTE_DBL).append(FIELD_ID).append(SqlUtils.QUOTE_DBL).append(SqlUtils.COLON).append(vId)
                        .append(SqlUtils.COMMA)
                        .append(SqlUtils.QUOTE_DBL).append(FIELD_NAME).append(SqlUtils.QUOTE_DBL).append(SqlUtils.COLON).append(SqlUtils.QUOTE_DBL).append(vName).append(SqlUtils.QUOTE_DBL)
                        .append(SqlUtils.COMMA)
                        .append(SqlUtils.QUOTE_DBL).append(FIELD_VALUE).append(SqlUtils.QUOTE_DBL).append(SqlUtils.COLON).append(vTradeValue)
                        .append(SqlUtils.COMMA)
                        .append(SqlUtils.QUOTE_DBL).append(FIELD_SELECTED).append(SqlUtils.QUOTE_DBL).append(SqlUtils.COLON).append(vSelected)
                        .append(SqlUtils.COMMA)
                        .append(SqlUtils.QUOTE_DBL).append(FIELD_CODE).append(SqlUtils.QUOTE_DBL).append(SqlUtils.COLON).append(SqlUtils.QUOTE_DBL).append(vCode).append(SqlUtils.QUOTE_DBL)
                        .append(SqlUtils.COMMA)
                        .append(SqlUtils.QUOTE_DBL).append(FIELD_URL_CODE).append(SqlUtils.QUOTE_DBL).append(SqlUtils.COLON).append(SqlUtils.QUOTE_DBL).append(vUrlCode).append(SqlUtils.QUOTE_DBL)
                        .append(SqlUtils.COMMA)
                        .append(SqlUtils.QUOTE_DBL).append(FIELD_COLOR).append(SqlUtils.QUOTE_DBL).append(SqlUtils.COLON).append(SqlUtils.QUOTE_DBL).append(vColor).append(SqlUtils.QUOTE_DBL);

                // <editor-fold defaultstate="collapsed" desc="CLOSE">
                if (results.size() == i + 1) {

                    while (levels.size() > 1) {
                        levels.remove(levels.size() - 1);
                        buf
                                .append(SqlUtils.BRACKET_FIGURE_RIGHT)
                                .append(SqlUtils.BRACKET_SQUARE_RIGHT);
                    }
                    buf.append(SqlUtils.BRACKET_FIGURE_RIGHT);
                }
                // </editor-fold>

            }
        }

        buf.append(SqlUtils.BRACKET_SQUARE_RIGHT);

        return buf.toString();
    }

}
